//
//  IMFCMPushService.m
//  DualMediationSDK
//
//  Created by YeJary on 2025/1/27.
//

#import "IMFCMPushService.h"
#import "../../Utils/Logger/IMLogUtils.h"
#import "../TA/DMThinkingManager.h"
#import <Foundation/Foundation.h>

#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#endif

#import <Firebase/Firebase.h>
#import <FirebaseMessaging/FirebaseMessaging.h>

@interface IMFCMPushService () <UNUserNotificationCenterDelegate, FIRMessagingDelegate>

@property (nonatomic, assign) BOOL fcmInitialized;
@property (nonatomic, strong, nullable) IMFCMPushConfig *currentConfig;
@property (nonatomic, copy, nullable) IMFCMNotificationReceivedBlock notificationReceivedCallback;
@property (nonatomic, copy, nullable) IMFCMTokenRefreshBlock tokenRefreshCallback;
@property (nonatomic, strong) dispatch_queue_t fcmQueue;
@property (nonatomic, copy, nullable) NSString *cachedFCMToken;

@end

@implementation IMFCMPushService

static IMFCMPushService *_sharedService = nil;
static dispatch_once_t _onceToken;

+ (instancetype)sharedService {
    dispatch_once(&_onceToken, ^{
        _sharedService = [[IMFCMPushService alloc] init];
    });
    return _sharedService;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _fcmInitialized = NO;
        _fcmQueue = dispatch_queue_create("com.dualmediationsdk.fcm", DISPATCH_QUEUE_SERIAL);
        [IMLogUtils info:IMLogTagAd format:@"IMFCMPushService initialized"];
    }
    return self;
}

#pragma mark - Public Methods

- (BOOL)isFCMInitialized {
    return self.fcmInitialized;
}

- (void)initializeFirebaseMessagingWithCompletion:(IMFCMPushCompletionBlock)completion {
    IMFCMPushConfig *config = [IMFCMPushConfig defaultConfig];
    [self initializeFirebaseMessagingWithConfig:config completion:completion];
}

- (void)initializeFirebaseMessagingWithTargetViewController:(Class)targetViewControllerClass completion:(IMFCMPushCompletionBlock)completion {
    IMFCMPushConfig *config = [IMFCMPushConfig configWithTargetViewControllerClass:targetViewControllerClass];
    [self initializeFirebaseMessagingWithConfig:config completion:completion];
}

- (void)initializeFirebaseMessagingWithConfig:(IMFCMPushConfig *)config completion:(IMFCMPushCompletionBlock)completion {
    if (!config) {
        IMFCMPushResult *result = [IMFCMPushResult failureWithCode:-3001 message:@"FCM配置不能为空"];
        [IMLogUtils error:IMLogTagAd format:@"FCM初始化失败: 配置为空"];
        if (completion) {
            completion(result);
        }
        return;
    }
    
    if (self.fcmInitialized) {
        IMFCMPushResult *result = [IMFCMPushResult successWithToken:self.cachedFCMToken];
        [IMLogUtils info:IMLogTagAd format:@"FCM已经初始化，返回缓存结果"];
        if (completion) {
            completion(result);
        }
        return;
    }
    
    [IMLogUtils info:IMLogTagAd format:@"开始初始化FCM推送服务: %@", config];
    
    // 埋点：推送初始化请求
    [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_init" properties:@{
        @"w_push_platform": @"fcm",
        @"w_show_in_foreground": @(config.showNotificationInForeground),
        @"w_auto_handle_tap": @(config.autoHandleNotificationTap),
        @"w_target_class": config.targetViewControllerClass ? NSStringFromClass(config.targetViewControllerClass) : @""
    }];
    [IMLogUtils info:IMLogTagAd format:@"📊 推送初始化埋点: platform=fcm, show_in_foreground=%@, auto_handle_tap=%@", 
     @(config.showNotificationInForeground), @(config.autoHandleNotificationTap)];
    
    dispatch_async(self.fcmQueue, ^{
        [self performFCMInitializationWithConfig:config completion:completion];
    });
}

- (NSString *)getCurrentFCMToken {
    return self.cachedFCMToken;
}

- (void)getFCMTokenWithCompletion:(IMFCMPushCompletionBlock)completion {
    if (!self.fcmInitialized) {
        IMFCMPushResult *result = [IMFCMPushResult failureWithCode:-3002 message:@"FCM未初始化"];
        if (completion) {
            completion(result);
        }
        return;
    }
    
    dispatch_async(self.fcmQueue, ^{
        [[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
            IMFCMPushResult *result;
            if (error) {
                result = [IMFCMPushResult failureWithCode:-3003 message:error.localizedDescription];
                [IMLogUtils error:IMLogTagAd format:@"获取FCM令牌失败: %@", error.localizedDescription];
            } else {
                result = [IMFCMPushResult successWithToken:token];
                self.cachedFCMToken = token;
                [IMLogUtils info:IMLogTagAd format:@"获取FCM令牌成功: %@", token];
            }
            
            if (completion) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(result);
                });
            }
        }];
    });
}

- (void)requestNotificationPermissionWithCompletion:(void (^)(BOOL, NSError * _Nullable))completion {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
    
    [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
        [IMLogUtils info:IMLogTagAd format:@"通知权限请求结果: granted=%@, error=%@", granted ? @"YES" : @"NO", error];
        
        // 埋点：推送权限请求结果
        [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_permission" properties:@{
            @"w_push_platform": @"fcm",
            @"w_permission_granted": @(granted),
            @"w_error_code": error ? @(error.code) : @0,
            @"w_error_message": error ? (error.localizedDescription ?: @"") : @""
        }];
        [IMLogUtils info:IMLogTagAd format:@"📊 推送权限埋点: platform=fcm, granted=%@, error=%@", 
         @(granted), error ? error.localizedDescription : @"无错误"];
        
        if (granted) {
#if TARGET_OS_IOS
            dispatch_async(dispatch_get_main_queue(), ^{
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            });
#endif
        }
        
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(granted, error);
            });
        }
    }];
}

- (void)checkNotificationPermissionWithCompletion:(void (^)(UNAuthorizationStatus))completion {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        [IMLogUtils info:IMLogTagAd format:@"当前通知权限状态: %ld", (long)settings.authorizationStatus];
        
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(settings.authorizationStatus);
            });
        }
    }];
}

- (void)setNotificationReceivedCallback:(IMFCMNotificationReceivedBlock)callback {
    self.notificationReceivedCallback = callback;
    [IMLogUtils info:IMLogTagAd format:@"设置通知接收回调: %@", callback ? @"已设置" : @"已清除"];
}

- (void)setTokenRefreshCallback:(IMFCMTokenRefreshBlock)callback {
    self.tokenRefreshCallback = callback;
    [IMLogUtils info:IMLogTagAd format:@"设置令牌刷新回调: %@", callback ? @"已设置" : @"已清除"];
}

- (void)handleRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [IMLogUtils info:IMLogTagAd format:@"处理远程通知: %@", userInfo];
    
    IMFCMNotificationInfo *notificationInfo = [IMFCMNotificationInfo infoWithUserInfo:userInfo source:@"Remote"];
    
    // 埋点：推送接收
    [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_received" properties:@{
        @"w_push_platform": @"fcm",
        @"w_push_source": @"remote",
        @"w_push_title": notificationInfo.title ?: @"",
        @"w_push_body": notificationInfo.body ?: @"",
        @"w_has_custom_data": @(notificationInfo.customData.count > 0)
    }];
    [IMLogUtils info:IMLogTagAd format:@"📊 推送接收埋点: platform=fcm, source=remote, title=%@", notificationInfo.title ?: @"无标题"];
    
    if (self.notificationReceivedCallback) {
        self.notificationReceivedCallback(notificationInfo);
    }
    
    // 处理自定义数据
    if (self.currentConfig && self.currentConfig.customDataHandler) {
        self.currentConfig.customDataHandler(userInfo);
    }
    
#if TARGET_OS_IOS
    if (completionHandler) {
        completionHandler(UIBackgroundFetchResultNewData);
    }
#endif
}

- (void)handleNotificationTap:(NSDictionary *)userInfo {
    [IMLogUtils info:IMLogTagAd format:@"处理通知点击: %@", userInfo];
    
    IMFCMNotificationInfo *notificationInfo = [IMFCMNotificationInfo infoWithUserInfo:userInfo source:@"Tap"];
    
    // 埋点：推送点击
    [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_click" properties:@{
        @"w_push_platform": @"fcm",
        @"w_push_source": @"tap",
        @"w_push_title": notificationInfo.title ?: @"",
        @"w_push_body": notificationInfo.body ?: @"",
        @"w_has_custom_data": @(notificationInfo.customData.count > 0),
        @"w_auto_handle": @(self.currentConfig.autoHandleNotificationTap)
    }];
    [IMLogUtils info:IMLogTagAd format:@"📊 推送点击埋点: platform=fcm, title=%@, auto_handle=%@", 
     notificationInfo.title ?: @"无标题", @(self.currentConfig.autoHandleNotificationTap)];
    
    if (self.notificationReceivedCallback) {
        self.notificationReceivedCallback(notificationInfo);
    }
    
    // 自动跳转到目标页面
    if (self.currentConfig && self.currentConfig.autoHandleNotificationTap && self.currentConfig.targetViewControllerClass) {
        [self navigateToTargetViewController:self.currentConfig.targetViewControllerClass];
    }
}

- (void)subscribeToTopic:(NSString *)topic completion:(void (^)(NSError * _Nullable))completion {
    if (!self.fcmInitialized) {
        NSError *error = [NSError errorWithDomain:@"IMFCMPushService" code:-3004 userInfo:@{NSLocalizedDescriptionKey: @"FCM未初始化"}];
        if (completion) {
            completion(error);
        }
        return;
    }
    
    [IMLogUtils info:IMLogTagAd format:@"订阅主题: %@", topic];
    
    [[FIRMessaging messaging] subscribeToTopic:topic completion:^(NSError * _Nullable error) {
        if (error) {
            [IMLogUtils error:IMLogTagAd format:@"订阅主题失败: %@", error.localizedDescription];
        } else {
            [IMLogUtils info:IMLogTagAd format:@"订阅主题成功: %@", topic];
        }
        
        if (completion) {
            completion(error);
        }
    }];
}

- (void)unsubscribeFromTopic:(NSString *)topic completion:(void (^)(NSError * _Nullable))completion {
    if (!self.fcmInitialized) {
        NSError *error = [NSError errorWithDomain:@"IMFCMPushService" code:-3004 userInfo:@{NSLocalizedDescriptionKey: @"FCM未初始化"}];
        if (completion) {
            completion(error);
        }
        return;
    }
    
    [IMLogUtils info:IMLogTagAd format:@"取消订阅主题: %@", topic];
    
    [[FIRMessaging messaging] unsubscribeFromTopic:topic completion:^(NSError * _Nullable error) {
        if (error) {
            [IMLogUtils error:IMLogTagAd format:@"取消订阅主题失败: %@", error.localizedDescription];
        } else {
            [IMLogUtils info:IMLogTagAd format:@"取消订阅主题成功: %@", topic];
        }
        
        if (completion) {
            completion(error);
        }
    }];
}

- (void)setUserProperty:(NSString *)value forKey:(NSString *)key {
    [IMLogUtils info:IMLogTagAd format:@"设置用户属性: %@=%@", key, value];
    
    // Firebase Messaging 不直接支持用户属性设置
    // 可以通过 Firebase Analytics 设置用户属性
    // [FIRAnalytics setUserPropertyString:value forName:key];
    [IMLogUtils info:IMLogTagAd format:@"用户属性设置完成: %@=%@", key, value];
}

- (void)setAutoInitEnabled:(BOOL)enabled {
    [IMLogUtils info:IMLogTagAd format:@"设置自动初始化: %@", enabled ? @"启用" : @"禁用"];
    
    [FIRMessaging messaging].autoInitEnabled = enabled;
    [IMLogUtils info:IMLogTagAd format:@"Firebase Messaging 自动初始化设置完成: %@", enabled ? @"启用" : @"禁用"];
}

- (void)handleNotificationTap:(NSDictionary *)userInfo viewController:(UIViewController *)viewController {
    [IMLogUtils info:IMLogTagAd format:@"处理通知点击（带视图控制器）: %@", userInfo];
    
    // 创建通知信息对象
    IMFCMNotificationInfo *notificationInfo = [IMFCMNotificationInfo infoWithUserInfo:userInfo source:@"Tap"];
    
    // 如果有通知接收回调，先调用
    if (self.notificationReceivedCallback) {
        self.notificationReceivedCallback(notificationInfo);
    }
    
    // 如果提供了视图控制器，在其上进行导航
    if (viewController) {
        dispatch_async(dispatch_get_main_queue(), ^{
            // 这里可以根据通知内容进行自定义导航
            [IMLogUtils info:IMLogTagAd format:@"在指定视图控制器上处理通知导航"];
        });
    } else if (self.currentConfig && self.currentConfig.targetViewControllerClass) {
        // 如果没有提供视图控制器但有配置的目标页面，使用配置的目标页面
        [self navigateToTargetViewController:self.currentConfig.targetViewControllerClass];
    }
}

- (BOOL)isFCMNotification:(NSDictionary *)userInfo {
    if (!userInfo || ![userInfo isKindOfClass:[NSDictionary class]]) {
        return NO;
    }
    
    // 检查是否包含FCM特有的字段
    // FCM通知通常包含以下字段之一：
    // - gcm.message_id (FCM消息ID)
    // - google.c.a.e (FCM分析标识)
    // - aps (iOS推送标准字段)
    
    BOOL hasFCMFields = userInfo[@"gcm.message_id"] != nil ||
                       userInfo[@"google.c.a.e"] != nil ||
                       userInfo[@"google.c.a.c_id"] != nil ||
                       userInfo[@"google.c.a.c_l"] != nil ||
                       userInfo[@"google.c.a.ts"] != nil;
    
    // 也检查是否有自定义的FCM标识
    BOOL hasCustomFCMFlag = [userInfo[@"fcm_notification"] boolValue] ||
                           [userInfo[@"from_fcm"] boolValue] ||
                           userInfo[@"fcm_token"] != nil;
    
    BOOL isFCM = hasFCMFields || hasCustomFCMFlag;
    
    [IMLogUtils info:IMLogTagAd format:@"检查FCM通知: %@ (结果: %@)", userInfo, isFCM ? @"是" : @"否"];
    
    return isFCM;
}

#pragma mark - Private Methods

- (void)performFCMInitializationWithConfig:(IMFCMPushConfig *)config completion:(IMFCMPushCompletionBlock)completion {
    @try {
        [IMLogUtils info:IMLogTagAd format:@"开始FCM初始化"];
        
        // 配置Firebase
        if (![FIRApp defaultApp]) {
            [FIRApp configure];
            [IMLogUtils info:IMLogTagAd format:@"Firebase App 配置完成"];
        }
        
        // 设置消息代理
        [FIRMessaging messaging].delegate = self;
        
        // 设置通知中心代理
        [UNUserNotificationCenter currentNotificationCenter].delegate = self;
        
        // 获取FCM令牌
        [[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
            IMFCMPushResult *result;
            if (error) {
                result = [IMFCMPushResult failureWithCode:-3003 message:error.localizedDescription];
                [IMLogUtils error:IMLogTagAd format:@"FCM初始化失败: %@", error.localizedDescription];
            } else {
                self.fcmInitialized = YES;
                self.currentConfig = config;
                self.cachedFCMToken = token;
                result = [IMFCMPushResult successWithToken:token];
                [IMLogUtils info:IMLogTagAd format:@"FCM初始化成功: %@", token];
            }
            
            if (completion) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(result);
                });
            }
        }];
        
    } @catch (NSException *exception) {
        [IMLogUtils error:IMLogTagAd format:@"FCM初始化异常: %@", exception.reason];
        
        IMFCMPushResult *result = [IMFCMPushResult failureWithCode:-3005 message:exception.reason];
        if (completion) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(result);
            });
        }
    }
}

- (void)navigateToTargetViewController:(Class)targetClass {
    if (!targetClass) {
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
#if TARGET_OS_IOS
        UIViewController *targetVC = [[targetClass alloc] init];
        
        UIWindow *keyWindow = nil;
        if (@available(iOS 13.0, *)) {
            UIWindowScene *windowScene = nil;
            for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
                if ([scene isKindOfClass:[UIWindowScene class]]) {
                    windowScene = (UIWindowScene *)scene;
                    if (windowScene.activationState == UISceneActivationStateForegroundActive) {
                        keyWindow = windowScene.windows.firstObject;
                        break;
                    }
                }
            }
        } else {
            keyWindow = [UIApplication sharedApplication].keyWindow;
        }
        
        UIViewController *rootVC = keyWindow.rootViewController;
        if (rootVC) {
            if ([rootVC isKindOfClass:[UINavigationController class]]) {
                [(UINavigationController *)rootVC pushViewController:targetVC animated:YES];
            } else {
                [rootVC presentViewController:targetVC animated:YES completion:nil];
            }
            
            [IMLogUtils info:IMLogTagAd format:@"导航到目标页面: %@", NSStringFromClass(targetClass)];
        }
#endif
    });
}

#pragma mark - FIRMessagingDelegate

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    [IMLogUtils info:IMLogTagAd format:@"FCM令牌刷新: %@", fcmToken];
    
    // 更新缓存的令牌
    self.cachedFCMToken = fcmToken;
    
    // 埋点：令牌刷新
    [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_token_refresh" properties:@{
        @"w_push_platform": @"fcm",
        @"w_token_length": @(fcmToken.length),
        @"w_token_prefix": fcmToken.length > 10 ? [fcmToken substringToIndex:10] : fcmToken
    }];
    [IMLogUtils info:IMLogTagAd format:@"📊 FCM令牌刷新埋点: platform=fcm, token_length=%@", @(fcmToken.length)];
    
    // 调用令牌刷新回调
    if (self.tokenRefreshCallback) {
        self.tokenRefreshCallback(fcmToken);
    }
}

// Note: The didReceiveMessage delegate method is deprecated in newer Firebase versions.
// FCM now uses APNs for message delivery. Messages are handled through UNUserNotificationCenter delegate methods.

#pragma mark - UNUserNotificationCenterDelegate

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    [IMLogUtils info:IMLogTagAd format:@"前台收到通知: %@", notification.request.content.userInfo];
    
    // 检查是否是FCM通知
    if ([self isFCMNotification:notification.request.content.userInfo]) {
        IMFCMNotificationInfo *notificationInfo = [IMFCMNotificationInfo infoWithUserInfo:notification.request.content.userInfo source:@"Foreground"];
        
        // 埋点：推送前台展示
        [[DMThinkingManager sharedManager] thinkingTrackEventWithKey:@"SDK_push_show" properties:@{
            @"w_push_platform": @"fcm",
            @"w_push_source": @"foreground",
            @"w_push_title": notificationInfo.title ?: @"",
            @"w_push_body": notificationInfo.body ?: @"",
            @"w_has_custom_data": @(notificationInfo.customData.count > 0),
            @"w_will_show": @(self.currentConfig.showNotificationInForeground)
        }];
        [IMLogUtils info:IMLogTagAd format:@"📊 推送前台展示埋点: platform=fcm, title=%@, will_show=%@", 
         notificationInfo.title ?: @"无标题", @(self.currentConfig.showNotificationInForeground)];
        
        if (self.notificationReceivedCallback) {
            self.notificationReceivedCallback(notificationInfo);
        }
        
        // 根据配置决定是否在前台显示通知
        if (self.currentConfig.showNotificationInForeground) {
            completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge);
        } else {
            completionHandler(UNNotificationPresentationOptionNone);
        }
    } else {
        // 非FCM通知，使用默认处理
        completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge);
    }
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    [self handleNotificationTap:userInfo];
    
    completionHandler();
}

@end
